import axios from 'axios'

import {
  ElNotification,
  ElMessageBox,
  ElMessage,
  ElLoading,
} from 'element-plus'
import {
  getRefreshToken,
  getToken,
  getExpires,
  setExpires,
  setRefreshToken,
  setToken,
} from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from '@/utils/common'
import Cookies from 'js-cookie'
import cache from '@/plugins/cache'
import { saveAs } from 'file-saver'
import useUserStore from '@/store/modules/user'
import { RefreshingAccessToken } from '@/api/refresh'
import useAppStore from '@/store/modules/app'

const router = useRouter()
// 辅助函数，用于判断是否为对象（排除 null 和数组）
function isObject(value) {
  return value !== null && typeof value === 'object' && !Array.isArray(value)
}
let downloadLoadingInstance
// 是否显示重新登录
export let isRelogin = { show: false }
import { loadConfig, appConfig } from '@/utils/config/globalConfig'
import { nextTick } from 'vue'
async function getConfig() {
  if (!appConfig.ENV || !appConfig.environments) {
    await loadConfig() // 确保 `globalConfig.json` 先加载
  }
  return appConfig.environments[appConfig.ENV]
}
const APP_ENV = await getConfig()
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'

const service = axios.create({
  baseURL: APP_ENV.base,
  timeout: 10000,
})

// 是否正在刷新的标志
let isRefreshing = false
let requestsQueue = [] //请求队列

// request拦截器
service.interceptors.request.use(
  (config) => {
    const { baseApi, baseApi02 } = APP_ENV
    if (process.env.NODE_ENV === 'development') {
      config.baseURL = '/api' // 让 Vue 代理生效
    } else {
      if (config.url.startsWith('/basic')) {
        config.baseURL = baseApi
        config.url = config.url.replace('/basic', `/api/v0/base`) // 根据代理规则修改路径
      } else if (config.url.startsWith('/sys')) {
        config.baseURL = baseApi
        config.url = config.url.replace('/sys', `/api/v0/sys`) // sys 也要修改
      } else if (config.url.startsWith('/Interface')) {
        config.baseURL = baseApi02
        config.url = config.url.replace('/Interface', `/api/Interface`) // 保持一致
      } else if (config.url.startsWith('/attachment')) {
        config.baseURL = baseApi
        config.url = config.url.replace('/attachment', `/api/v0/attachment`) // 保持一致
      }
    }
    const appStore = useAppStore()
    const operateSysId = computed(() => appStore.operateSysId)
    const isNeedFixParmas = (config.headers || {}).isNeedFixParmas === true //是否固定参数

    if (getToken()) {
      config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
    }
    const DATA = {
      applicationType: 1,
      application: operateSysId.value,
      application_version: 'v1.0',
      operator_account: '',
      input: isObject(config.data)
        ? JSON.parse(JSON.stringify(config.data))
        : config.data === ''
        ? ''
        : config.data,
    }
    config.data = isNeedFixParmas ? DATA : config.data

    // get请求映射params参数
    if (config.method === 'get' && config.params) {
      let url = config.url + '?' + tansParams(config.params)
      url = url.slice(0, -1)
      config.params = {}
      config.url = url
    }

    if (getToken()) {
      const token = getToken()
      const expires = getExpires()
      const refreshUrl =
        process.env.NODE_ENV == 'development'
          ? '/basic/RefreshingAccessToken'
          : '/api/v0/base/RefreshingAccessToken'
      // 检查 token 是否快过期（30 分钟内）
      // 1890000 30 * 60 * 1000
      const isTokenExpiring = expires - Date.now() < 30 * 60 * 1000 // 30分钟内过期
      if (expires && isTokenExpiring && !config.url.includes(refreshUrl)) {
        if (!isRefreshing) {
          isRefreshing = true
          RefreshingAccessToken({ refresh_token: getRefreshToken() })
            .then((res) => {
              // 更新token值
              const data = res.output

              nextTick(() => {
                setToken(data.access_token)
                setRefreshToken(data.refresh_token)
                let time = Date.parse(new Date(data.expires).toString()) //将过期时间转为时间戳
                setExpires(time) //设置过期时间
                // 将刷新的token替代老的token
                config.headers['Authorization'] = 'Bearer ' + data.access_token
                requestsQueue.forEach((cb) => cb(data.access_token))
                requestsQueue = [] // 重新请求完清空
              })
            })
            .catch((err) => {
              ElNotification.error({ title: err.msg })
              useUserStore()
                .logOut()
                .then(() => {
                  location.href = '/index'
                })
            })
            .finally(() => {
              //无论是否有触发异常，该语句都会执行
              isRefreshing = false
            })
          //避免刷新401

          return new Promise((resolve) => {
            requestsQueue.push((token) => {
              config.headers['Authorization'] = 'Bearer ' + token
              resolve(config)
            })
          })
        } else {
          return new Promise((resolve) => {
            requestsQueue.push((token) => {
              config.headers['Authorization'] = 'Bearer ' + token
              resolve(config)
            })

            // console.log(222222, requestsQueue)
          })
        }
      }
    }

    return config
  },
  (error) => {
    Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  (res) => {
    // 未设置状态码则默认成功状态
    const code = res.data.code
    const msg = res.data.msg
    const data = res.data
    // 二进制数据则直接返回
    if (
      res.request.responseType === 'blob' ||
      res.request.responseType === 'arraybuffer'
    ) {
      return data
    }

    if (code != 1) {
      ElMessage({ message: msg, type: 'error' })
      return Promise.reject(new Error(msg))
    } else {
      return Promise.resolve(data)
    }
  },
  (error) => {
    console.log('response--error', error)
    let { message } = error

    if (message == 'Network Error') {
      message = '后端接口连接异常'
    } else if (message.includes('timeout')) {
      message = '系统接口请求超时'
    } else if (message.includes('Request failed with status code')) {
      message = '系统接口' + message.substr(message.length - 3) + '异常'
    }
    ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
    return Promise.reject(error)
  }
)

// 通用下载方法
export function download(url, params, filename, config) {
  downloadLoadingInstance = ElLoading.service({
    text: '正在下载数据，请稍候',
    background: 'rgba(0, 0, 0, 0.7)',
  })

  const query = tansParams(params) // 拼接 query 字符串
  const fullUrl = `${url}?${query}`

  return service
    .get(fullUrl, {
      responseType: 'blob',
      ...config,
    })
    .then(async (data) => {
      const isBlob = await blobValidate(data)
      if (isBlob) {
        const blob = new Blob([data])
        saveAs(blob, filename)
      } else {
        const resText = await data.text()
        const rspObj = JSON.parse(resText)
        const errMsg =
          errorCode[rspObj.code] || rspObj.msg || errorCode['default']
        ElMessage.error(errMsg)
      }
      downloadLoadingInstance.close()
    })
    .catch((error) => {
      console.error(error)
      ElMessage.error('下载文件出现错误，请联系管理员！')
      downloadLoadingInstance.close()
    })
}
// export function download(url, params, filename, config) {
//   downloadLoadingInstance = ElLoading.service({
//     text: '正在下载数据，请稍候',
//     background: 'rgba(0, 0, 0, 0.7)',
//   })
//   return service
//     .post(url, params, {
//       transformRequest: [
//         (params) => {
//           return tansParams(params)
//         },
//       ],
//       headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
//       responseType: 'blob',
//       ...config,
//     })
//     .then(async (data) => {
//       const isBlob = blobValidate(data)
//       if (isBlob) {
//         const blob = new Blob([data])
//         saveAs(blob, filename)
//       } else {
//         const resText = await data.text()
//         const rspObj = JSON.parse(resText)
//         const errMsg =
//           errorCode[rspObj.code] || rspObj.msg || errorCode['default']
//         ElMessage.error(errMsg)
//       }
//       downloadLoadingInstance.close()
//     })
//     .catch((r) => {
//       console.error(r)
//       ElMessage.error('下载文件出现错误，请联系管理员！')
//       downloadLoadingInstance.close()
//     })
// }

export default service
